﻿using Batman.Authentication.Middlewares;
using Batman.Authentication.Utils;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace Microsoft.AspNetCore.Builder
{
    public class BatmanAuthentication : Batman.Core.Middlewares.MiddlewareBase
    {
        static ActionDescriptor _emptyActionDescriptor = new ActionDescriptor();

        static RouteData _emptyRouteData = new RouteData();

        public BatmanAuthentication(RequestDelegate next) : base(next)
        {
        }

        public override async Task Invoke(HttpContext context)
        {
            var routeData = context.GetRouteData() ?? _emptyRouteData;
            CreateActionDescriptor<string>(routeData.Values["action"].ToString(), routeData);
            //ControllerActionDescriptorBuilder
           //var authenticationInfo = context.Request.Headers["Authorization"];
           //var token = authenticationInfo.FirstOrDefault();
           //token = string.IsNullOrEmpty(token) ? string.Empty : token.Replace("Bearer ", string.Empty);
           //var securityToken = JwtTokenUtil.ParseToken(token);

           //// 约定 // TODO: 放在统一的地方
           //var userIdClaim = securityToken.Claims.FirstOrDefault(t => t.Type == "userId");
           //var userId = userIdClaim == null ? string.Empty : userIdClaim.Value;

           //var path = context.Request.Path;

           // TODO: 获取角色和应用
           // 获取即将要访问的资源
           // 对比权限
           // 返回或者next
           // 组织设计返回格式
           await _next(context);
        }

        private static ActionDescriptor CreateActionDescriptor<TController>(string actionName, RouteData routeData)
        {
            var controllerType = typeof(TController);
            var actionDesciptor = new ControllerActionDescriptor()
            {
                ControllerName = controllerType.Name,
                ActionName = actionName,
                FilterDescriptors = new List<FilterDescriptor>(),
                MethodInfo = controllerType.GetMethod(actionName, BindingFlags.Public | BindingFlags.Instance),
                ControllerTypeInfo = controllerType.GetTypeInfo(),
                Parameters = new List<ParameterDescriptor>(),
                Properties = new Dictionary<object, object>(),
                BoundProperties = new List<ParameterDescriptor>()
            };

            return actionDesciptor;
        }
    }
}
